import datetime
import random,pickle,os
import time
from ATM系统项目.package.CardClass import Card
from ATM系统项目.package.PersonClass import Person
class Control():
    # 数据存储格式
    userid_cardid_dict={}  # {身份码:银行卡ID}
    cardid_userobj_dict={}   # {银行卡ID:用户对象}
    # 数据存储的url
    user_file_url='./database/user.txt'
    card_file_url='./database/userid.txt'
    def __init__(self):
        # 加载所有信息
        self.__loaddata()
        # 获取用户信息
    def __loaddata(self):
        if os.path.exists(self.card_file_url):
            with open(self.card_file_url, 'rb') as fp1:
                while True:
                    try:
                        self.userid_cardid_dict = pickle.load(fp1)
                    except:
                        break
        if os.path.exists(self.card_file_url):
            with open(self.user_file_url, 'rb') as fp2:
                while True:
                    try:
                        self.cardid_userobj_dict=pickle.load(fp2)
                    except:
                        break
        print(self.cardid_userobj_dict)
        print(self.userid_cardid_dict)

    # 1.注册
    def register(self):
        # 获取用户名，身份证号，手机号，密码
        username = self.__getusername()
        password = self.__getpassword()
        userid = self.__getuserid()
        phone = self.__getuserphone()
        print(username,password,userid,phone)
        # 给用户创建一个银行卡,卡id不重复
        while True:
            cardid = str(random.randint(100000,999999))
            if cardid not in self.cardid_userobj_dict:
                cardobj = Card(cardid,password)
                break
            else:
                continue
        # 创建用户对象与银行卡进行绑定
        userobj = Person(username,userid,phone,cardobj)
        # 保存用户信息{身份码：银行卡ID}、{银行卡ID:用户对象}
        self.userid_cardid_dict[userid]=cardid
        self.cardid_userobj_dict[cardid]=userobj
        # 完成创建
        print(f'恭喜{username}开户成功，您的卡号为：{cardid}，余额为{cardobj.money}')
    # 2.查询
    def search(self):
        # 获取用户卡号
        cardid = input('请输入你的卡号：')
        # 验证卡号是否存在和卡是否被锁定
        if self.__getcardid(cardid):
            # 获取卡对象
            cardobj = self.cardid_userobj_dict[cardid].card
            # 验证密码是否正确
            if self.__checkpwd(cardobj):
                print(f'您当前的卡号为：{cardid},余额为：{cardobj.money}')
        else:
            return
    # 3.存钱
    def save_money(self):
        # 获取用户卡号
        cardid = input('请输入你的卡号：')
        # 验证卡号是否存在和卡是否被锁定
        if self.__getcardid(cardid):
            cardobj = self.cardid_userobj_dict[cardid].card
            # 卡状态正常开始存钱
            while True:
                try:
                    savemoney=int(input('请输入您想要存入的金额：'))
                except:
                    print('请输入正确的数字')
                    continue
                if savemoney<=0:
                    print('您输入的金额有误！')
                    continue
                else:
                    cardobj.money+=savemoney
                    # 保存交易记录
                    transfer_info_url = f'./database/{cardid}info.txt'
                    res=f'{datetime.datetime.now()}，卡号{cardid}存入金额为{savemoney}\n'
                    with open(transfer_info_url,'a') as file1:
                        file1.write(res)
                    print(f'存入金额为{savemoney},卡里余额为：{cardobj.money}')
                    break
    # 4.取钱
    def withdraw(self):
        # 获取用户卡号
        cardid = input('请输入您的卡号：')
        # 验证卡号是否存在和卡是否被锁定
        if self.__getcardid(cardid):
            cardobj=self.cardid_userobj_dict[cardid].card
            # 没有锁定，验证密码是否正确
            if self.__checkpwd(cardobj):
                # 正确，开始取钱
                while True:
                    try:
                        withdraw=int(input('请输入您想要提取的金额：'))
                    except:
                        print('请输入正确的数字')
                        continue
                    if withdraw>cardobj.money:
                        print('余额不足！')
                        continue
                    elif withdraw<=0:
                        print('您输入的金额有误！')
                        continue
                    else:
                        cardobj.money-=withdraw
                        transfer_info_url = f'./database/{cardid}info.txt'
                        res = f'{datetime.datetime.now()}，卡号{cardid}取出金额为{withdraw}\n'
                        with open(transfer_info_url,'a') as file1:
                            file1.write(res)
                        print(f'取出的金额为{withdraw},卡里余额为：{cardobj.money}')
                        break
        else:
            return
    # 5.转账
    def transfer(self):
        # 获取用户卡号
        cardid1 = input('请输入您的卡号：')
        # 验证卡号是否存在和是否被锁定
        if self.__getcardid(cardid1):
            cardobj1 = self.cardid_userobj_dict[cardid1].card
            # 获取对方卡号
            cardid2 = input('请输入对方的卡号：')
            if cardid2==cardid1:
                print('不可以给自己转账！')
                return
            # 验证对方卡号是否存在
            if cardid2 not in self.cardid_userobj_dict:
                print('此卡号不存在')
                return
            cardobj2 = self.cardid_userobj_dict[cardid2].card
            # 验证密码
            if self.__checkpwd(cardobj1):
                # 密码正确，开始转账
                while True:
                    try:
                        transfer=int(input('请输入您转账的金额：'))
                    except:
                        print('请输入正确的数字')
                        continue
                    if transfer<0:
                        print('输入金额错误')
                        continue
                    if transfer>cardobj1.money:
                        print('余额不足！')
                        continue
                    cardobj1.money-=transfer
                    cardobj2.money+=transfer
                    transfer_info_url = f'./database/{cardid1}info.txt'
                    res=f'{datetime.datetime.now()}，卡号{cardid1}转账金额为{transfer}，收款方{cardid2}\n'
                    with open(transfer_info_url,'a') as file1:
                        file1.write(res)
                    print(f'您转出的金额为：{transfer},当前余额为：{cardobj1.money}')
                    break
        else:
            return
    # 6.改密
    def change_density(self):
        print('请输入您的卡号或身份码进行修改密码')
        # 获取用户身份码或卡号
        uoc_id=input('请输入您的卡号或身份码：')
        if uoc_id not in {**self.cardid_userobj_dict,**self.userid_cardid_dict}:
            print('您输入的身份码或卡号不存在！')
            return
        # 用户输入为卡号
        if uoc_id in self.cardid_userobj_dict:
            cardobj=self.cardid_userobj_dict[uoc_id].card
        # 判断新密码是否与旧密码一致
            while True:
                if self.__getpassword()==cardobj.password:
                    print('新密码不能和旧密码一致！')
                    continue
                else:
                    print('新密码修改成功')
                    break
        # 用户输入为身份码
        if uoc_id in self.userid_cardid_dict:
            cardobj=self.cardid_userobj_dict[self.userid_cardid_dict[uoc_id]].card
            while True:
                if self.__getpassword()==cardobj.password:
                    print('新密码不能和旧密码一致！')
                    continue
                else:
                    print('新密码修改成功')
                    break
    # 7.锁卡
    def lock_card(self):
        # 获取用户卡号
        cardid=input('请输入您的卡号：')
        # 判断卡号是否存在或被锁定
        if self.__getcardid(cardid):
            # 没有锁定,输入密码或身份证锁定
            cardobj=self.cardid_userobj_dict[cardid].card
            while True:
                pwdorusid=input('请输入密码或身份码进行锁定：')
                # 用户输入密码，判断密码是否一致
                if pwdorusid==cardobj.password:
                    cardobj.islock=True
                    print('卡已成功锁定')
                    break
                # 用户输入身份码
                elif pwdorusid==self.cardid_userobj_dict[cardid].userid:
                    cardobj.islock = True
                    print('卡已成功锁定')
                    break
                else:
                    print('密码或身份码不一致！')
                    continue
    # 8.解锁
    def unlock(self):
        # 获取用户卡号
        cardid=input('请输入您的卡号：')
        # 判断卡号是否存在
        if cardid not in self.cardid_userobj_dict:
            print('卡号不存在！')
            return
        cardobj=self.cardid_userobj_dict[cardid].card
        userobj=self.cardid_userobj_dict[cardid]
        # 锁定，进行解锁
        if cardobj.islock:
            while True:
                userid=input('请输入您的身份码：')
                if userid==userobj.userid:
                    cardobj.islock=False
                    print('您的卡已成功解锁')
                    break
                else:
                    print('身份码不一致！')
                    continue
        else:
            print('您的卡目前没有锁定，可以正常使用')
    # 9.补卡
    def reset(self):
        # 获取用户身份码
        userid=input('请输入您的身份码：')
        # 判断身份码是否存在
        if userid not in self.userid_cardid_dict:
            print('当前身份码不存在！')
            return
        # 存在
        else:
            while True:
                new_cardid = str(random.randint(100000, 999999))
                if new_cardid not in self.cardid_userobj_dict:
                    # 修改卡id{cardid:userobj}==>{new_cardid:userobj}
                    self.cardid_userobj_dict[new_cardid] = self.cardid_userobj_dict[self.userid_cardid_dict[userid]]
                    # 旧卡作废，删除原本的{cardid:userobj}
                    del self.cardid_userobj_dict[self.userid_cardid_dict[userid]]
                    # 修改身份码对应的id{userid:cardid}==>{userid:new_cardid}
                    self.userid_cardid_dict[userid] = new_cardid
                    print(f'已为您补卡成功，您的新卡号为{new_cardid}')
                    break
                else:
                    continue
    # 0.退出
    def quit(self):
        with open(self.card_file_url,'ab+') as file1:
            pickle.dump(self.userid_cardid_dict,file1)
        with open(self.user_file_url,'ab+') as file2:
            pickle.dump(self.cardid_userobj_dict,file2)
        print('正在退出...')
    # a.查询记录
    def query_record(self):
        # 获取用户卡号
        cardid=input('请输入您的卡号：')
        # 判断卡号是否存在
        if cardid in self.cardid_userobj_dict:
            transfer_info_url = f'./database/{cardid}info.txt'
            with open(transfer_info_url,'r') as file:
                res=file.read()
                print('-----------当前交易记录如下-----------')
                print(res)
        else:
            print('当前卡号不存在')
            return

    # 获取用户名的私有方法
    def __getusername(self):
        while True:
            username = input('用户名只能由数字、字母和下划线组成！请输入您的用户名：')
            if not username.isidentifier():
                print('您输入的用户名含非法字符！！')
                continue
            else:
                print('创建成功')
                return username
    # 获取用户身份码的私有方法
    def __getuserid(self):
        while True:
            userid = input('身份码只能包含数字！请输入您的身份码：')
            if not userid.isdecimal():
                print('您输入的身份码含非法字符！！')
                continue
            elif userid in self.userid_cardid_dict:
                    print('当前身份码已存在')
            else:
                print('身份码创建成功')
                return userid
    # 获取用户手机号的私有方法
    def __getuserphone(self):
        while True:
            phone = input('请输入您的手机号：')
            if not phone.isdecimal() or len(phone)!=11:
                print('您输入的手机号有误！！')
                continue
            else:
                return phone
    # 获取用户密码的私有方法
    def __getpassword(self):
        while True:
            password = input('密码不能小于6位，只能由字母开头，并且和数字或下划线组成，请输入您的密码：')
            if password.isdecimal() or password.isalpha() or len(password)<6:
                print('您输入的密码不够安全！')
                continue
            elif not password.isidentifier():
                print('您输入的密码含非法字符！')
                continue
            elif not password[0].encode('UTF-8').isalpha():
                print('密码请以字母开头！')
            else:
                repwd=input('请再次输入密码进行确认：')
                if repwd==password:
                    return password
                else:
                    print('两次密码输入不一致')
                    continue
    # 检测密码是否正确
    def __checkpwd(self,cardobj):
        num=3  # 三次输入密码的机会
        while True:
            # 获取密码
            pwd=input('请输入您的密码：')
            if pwd==cardobj.password:
                return True
            else:
                num-=1
                if num == 0:
                    cardobj.islock=True
                    print('您当前的卡已经锁定')
                    break
                print(f'密码错误，您还有{num}次机会')
    # 检测卡的状态
    def __getcardid(self,cardid):
        # 验证卡号是否存在
        if cardid not in self.cardid_userobj_dict:
            print('当前卡号不存在！')
            return False
        # 卡号存在
        else:
            # 判断是否锁卡
            if self.cardid_userobj_dict[cardid].card.islock:
                print('当前卡已经锁定，请先解卡')
                return False
            else:
                return True


# 202751
'''      '''